﻿using SolidWorks.Interop.sldworks;
using SolidWorks.Interop.swconst;
using SwParaPlatform2.tools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace SwParaPlatform2
{
    public class DataStore
    {
        private static DataStore instance;

        private Dictionary<string, Dictionary<string, object>> dMainAssemblyData;
        private Dictionary<string, object> dTreeViewData;
        private Dictionary<string, string> parentChildMap;

        public Dictionary<string, object> dNote_NameData = new Dictionary<string, object>();
        public Dictionary<string, object> dName_NoteData = new Dictionary<string, object>();
        public Dictionary<string, Dictionary<string, object>> dNote_NameData_Pack = new Dictionary<string, Dictionary<string, object>>();
        public Dictionary<string, Dictionary<string, object>> dName_NoteData_Pack = new Dictionary<string, Dictionary<string, object>>();

        public Dictionary<string, Dictionary<string, object>> UIConfigData;
        public Dictionary<string, Dictionary<string, object>> RuleConfigData;
        public Dictionary<string, Dictionary<string, Dictionary<string, string>>> dEquationData 
            = new Dictionary<string, Dictionary<string, Dictionary<string, string>>>();
        public List<string> RenameSpace = new List<string>();
        public List<string> DrwList = new List<string>();

        public string sMainAssemName; //当前激活的模型文件名
        public string sDocPath; //配置文件对应的模型文件路径

        public string sParentPath; //sWorkingPath所在的文件夹
        public string sWorkingPath; //配置文件路径，由模型新建配置文件时创建
        public string sWorkingPath_New; //由配置文件打开的工作路径，替换时需要使用到这个工作当前路径，组合成完成路径

        // 映射字典
        public Dictionary<string, string> HeaderMapping { get; set; } = new Dictionary<string, string>
        {
            { "TypeName", "类型" },
            { "CompressState", "压缩状态" },
            { "Equation", "方程式" },
            { "Lenth", "长度" }
        };

        public Dictionary<string, object> UIGridData = new Dictionary<string, object>();

        // ViewConfig 字典
        public Dictionary<string, Dictionary<string, object>> ViewConfig { get; set; } = new Dictionary<string, Dictionary<string, object>>();

        private DataStore()
        {
        }

        public Dictionary<string, Dictionary<string, object>> ConvertInputData(Dictionary<string, object> inputData)
        {
            var result = new Dictionary<string, Dictionary<string, object>>();

            foreach (var kvp in inputData)
            {
                if (kvp.Value is Dictionary<string, object> subDict)
                {
                    result[kvp.Key] = subDict;
                }
                else
                {
                    throw new InvalidCastException($"Value for key '{kvp.Key}' is not a Dictionary<string, object>.");
                }
            }

            return result;
        }

        public static DataStore Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new DataStore();
                }
                return instance;
            }
        }

        public static void Reset()
        {
            instance = null;
        }

        public Dictionary<string, Dictionary<string, object>> MainAssemblyData
        {
            get { return dMainAssemblyData; }
            set { dMainAssemblyData = value; }
        }

        // 读取数据的接口
        public Dictionary<string, object> GetMainAssemblyDataByKey(string key)
        {
            if (dMainAssemblyData.ContainsKey(key))
            {
                return dMainAssemblyData[key];
            }
            return null;
        }

        // 修改数据的接口
        public void UpdateMainAssemblyData(string key, Dictionary<string, object> newData)
        {
            if (dMainAssemblyData.ContainsKey(key))
            {
                dMainAssemblyData[key] = newData;
            }
        }

        public Dictionary<string, object> TreeViewData
        {
            get { return dTreeViewData; }
            set { dTreeViewData = value; }
        }
        
        public Dictionary<string, Dictionary<string, Dictionary<string, string>>> EquationData
        {
            get { return dEquationData; }
            set { dEquationData = value; }
        }

        // 获取整个字典数据
        public Dictionary<string, object> GetTreeViewData()
        {
            return dTreeViewData;
        }

        // 更新整个字典数据
        public void UpdateTreeViewData(string path, Dictionary<string, object> updatedData)
        {
            var keys = path.Split('\\');
            var currentData = TreeViewData;

            for (int i = 0; i < keys.Length - 1; i++)
            {
                if (currentData.ContainsKey(keys[i]) && currentData[keys[i]] is Dictionary<string, object> tempData)
                {
                    if (tempData.ContainsKey("SubComp") && tempData["SubComp"] is Dictionary<string, object> subCompData)
                    {
                        currentData = subCompData;
                    }
                    else
                    {
                        return;
                    }
                }
            }

            var lastKey = keys[keys.Length - 1];
            if (currentData.ContainsKey(lastKey) && currentData[lastKey] is Dictionary<string, object> lastData)
            {
                if (lastData.ContainsKey("SubComp") && lastData["SubComp"] is Dictionary<string, object> lastSubCompData)
                {
                    lastData["SubComp"] = updatedData;
                }
            }
        }

        public Dictionary<string, object> GetMainMainSubComp(Dictionary<string, object> structure)
        {
            if(structure != null)
            {
                if (structure.TryGetValue("TypeName", out object typeName) && typeName.ToString() == "Main-Main")
                {
                    if (structure.TryGetValue("SubComp", out object subCompObj) && subCompObj is Dictionary<string, object> subComp)
                    {
                        if (subComp.Count == 1) // Ensure there's only one key-value pair
                        {
                            var firstSubComp = subComp.Values.First() as Dictionary<string, object>;
                            if (firstSubComp != null && firstSubComp.TryGetValue("SubComp", out object nestedSubCompObj) && nestedSubCompObj is Dictionary<string, object> nestedSubComp)
                            {
                                return nestedSubComp;
                            }
                        }
                    }
                }
            }
            return null;
        }

        public void InitParentChildMap()
        {
            TreeBuilder builder = new TreeBuilder();
            parentChildMap = new Dictionary<string, string>();
            var mainMainSubComp = GetMainMainSubComp(TreeViewData);
            if (mainMainSubComp != null)
            {
                foreach (var subComp in mainMainSubComp)
                {
                    DataTreeNode rootNode = builder.CreateNodeTree((Dictionary<string, object>)subComp.Value, subComp.Key);

                    // Update the parent-child map with each subtree's relationships
                    var currentParentChildMap = builder.CreateParentChildMap((Dictionary<string, object>)subComp.Value, subComp.Key);
                    foreach (var entry in currentParentChildMap)
                    {
                        parentChildMap[entry.Key] = entry.Value;
                    }
                }
            }
        }

        public Dictionary<string, string> GetParentChildMap()
        {
            return parentChildMap;
        }

        public void SaveNameNoteData(Dictionary<string, object> dNote_NameData_Push, Dictionary<string, object> dName_NoteData_Push)
        {
            dNote_NameData_Pack[Defines.Note_NameElementName] = dNote_NameData_Push;
            dName_NoteData_Pack[Defines.Name_NoteElementName] = dName_NoteData_Push;
            dNote_NameData = dNote_NameData_Push;
            dName_NoteData = dName_NoteData_Push;
        }

        public void SaveXmlData(string filePath, Dictionary<string, Dictionary<string, object>> dAllRuleConfigData)
        {
            string rootElementName = "RuleConfig";
            string drwElementName = "drwConfig";
            string UIElementName = "UIConfig";

            RuleConfigData = dAllRuleConfigData;

            int errors = 0;
            int warnings = 0;
            ModelDoc2 ActiveDoc = SwAppMgr.Instance.iSwApp.ActiveDoc;
            string DocPath = ActiveDoc.GetPathName();
            int iDocType = ActiveDoc.GetType();
            SwAppMgr.Instance.iSwApp.CloseDoc(ActiveDoc.GetTitle());

            XmlHandler.SaveAndPackConfigFile(filePath, UIConfigData, UIElementName);
            XmlHandler.SaveAndPackConfigFile(filePath, RuleConfigData, rootElementName);
            XmlHandler.SaveAndPackConfigFile(filePath, dNote_NameData_Pack, Defines.Note_NameElementName);
            XmlHandler.SaveAndPackConfigFile(filePath, dName_NoteData_Pack, Defines.Name_NoteElementName);

            Dictionary<string, Dictionary<string, object>> dDrwConfigData = new Dictionary<string, Dictionary<string, object>>()
            {
                { "drw", new Dictionary<string, object>()
                    {
                        { "drw", DrwList }  // 两个键都为 "drw"，值为 List<string>
                    }
                }
            };
            XmlHandler.SaveAndPackConfigFile(filePath, dDrwConfigData, drwElementName);

            IModelDoc2 modelDoc = SwAppMgr.Instance.iSwApp.OpenDoc6(DocPath, iDocType,
                (int)swOpenDocOptions_e.swOpenDocOptions_Silent, "", ref errors, ref warnings);
        }

        // 其他页面的数据接口可以按照类似的方式添加
    }

    public class DataTreeNode
    {
        public string Name { get; set; }
        public Dictionary<string, object> Data { get; set; }
        public List<DataTreeNode> Children { get; set; }

        public DataTreeNode(string name, Dictionary<string, object> data)
        {
            Name = name;
            Data = data;
            Children = new List<DataTreeNode>();
        }

        public void AddChild(DataTreeNode child)
        {
            Children.Add(child);
        }
    }

    public class TreeBuilder
    {
        public DataTreeNode CreateNodeTree(Dictionary<string, object> structure, string name)
        {
            if(name == null)
            {
                return null;
            }
            
            DataTreeNode node = new DataTreeNode(name, structure);

            if (structure.ContainsKey("SubComp"))
            {
                var subComponents = structure["SubComp"] as Dictionary<string, object>;
                foreach (var subComponent in subComponents)
                {
                    Dictionary<string, object> dSubChildComp = (Dictionary<string, object>)subComponent.Value;
                    string sChildTreeName;
                    if (dSubChildComp.TryGetValue("TempName", out var sTempName))
                    {
                        sChildTreeName = (string)sTempName;
                    }
                    else
                    {
                        sChildTreeName = null;
                    }

                    if(sChildTreeName != null)
                    {
                        DataTreeNode childNode = CreateNodeTree((Dictionary<string, object>)subComponent.Value, sChildTreeName);
                        node.AddChild(childNode);
                    }
                    
                }
            }

            return node;
        }

        public Dictionary<string, string> CreateParentChildMap(Dictionary<string, object> structure, string name)
        {
            Dictionary<string, string> parentChildMap = new Dictionary<string, string>();
            Queue<KeyValuePair<string, Dictionary<string, object>>> queue = new Queue<KeyValuePair<string, Dictionary<string, object>>>();
            queue.Enqueue(new KeyValuePair<string, Dictionary<string, object>>(name, structure));

            while (queue.Count > 0)
            {
                var current = queue.Dequeue();
                var currentName = current.Key;
                var currentStructure = current.Value;

                if (currentStructure.ContainsKey("Parent") && currentStructure["Parent"] != null)
                {
                    string parent = currentStructure["Parent"].ToString();
                    parentChildMap[currentName] = parent;
                }

                if (currentStructure.ContainsKey("SubComp"))
                {
                    var subComponents = currentStructure["SubComp"] as Dictionary<string, object>;
                    foreach (var subComponent in subComponents)
                    {
                        queue.Enqueue(new KeyValuePair<string, Dictionary<string, object>>(subComponent.Key, (Dictionary<string, object>)subComponent.Value));
                    }
                }
            }

            return parentChildMap;
        }
    }
}
